//*********************************************************************
//		Copyright (c) 2003 - 2008 Microsoft Corporation.
//      This code is provided under Microsoft Public License, which can be found at
//      http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx 
//
// @File: Exporter.cs
//
// Purpose: Exports data from the database and creates cab-file
//
//
//
// Notes: 
//
//
//	
// History: 
//     @Version: V2.1
//
//     07/14/08 PGV 2.1.001.0 Starting V2.1 (based on 2.0.030.0 code)
//
//
// @EndHeader@
//*********************************************************************

using System;
using System.IO;
using System.Diagnostics;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;

namespace H2V2
{
	enum ExportSessionType 
	{
		NEW = 0,
		FORCED
	}

    enum TableExportMode
    {
        WholeTable = 0,
        RunQuery,
        TopQuery,
        FileQuery
    }

    class TableToExport
    {
        string name;
        TableExportMode mode;
        bool specialDelimeter = false;
        uint topNumber = 0;

        public string Name { get { return name; } }
        public TableExportMode Mode { get { return mode; } }
        public bool SpecialDelimeter { get { return specialDelimeter; } }
        public uint TopNumber { get { return topNumber; } }

        public TableToExport (string a_name, TableExportMode a_mode)
        {
            name = a_name;
            mode = a_mode;
        }

        public TableToExport (string a_name, TableExportMode a_mode, bool a_delimeter)
        {
            name = a_name;
            mode = a_mode;
            specialDelimeter = a_delimeter;
        }

        public TableToExport (string a_name, TableExportMode a_mode, uint a_topNumber)
        {
            name = a_name;
            mode = a_mode;
            topNumber = a_topNumber;
        }
    }

	public class Exporter : StatusObject
	{
        const string QueryOutArgs = "\"{0}\" queryout \"{1}\" -S{2} -T -c -CRAW";
        const string EntireTableArgs = "{0}.dbo.{1} out \"{2}\" -S{3} -T -c -t, -CRAW";
        const string RunQueryArgs = 
            "SELECT t.* From {0}.dbo.{1} t JOIN {0}.dbo.x_runs x ON (t.run_id=x.run_id and x.sid={2})";
        const string FileQueryArgs = 
            "SELECT p.* From {0}.dbo.{1} p JOIN {0}.dbo.x_files x ON (p.fid=x.fid and x.sid={2})";
        const string TopQueryArgs = "Select TOP {0} * From {1}.dbo.{2}";
        const string RegularDelimiterArg = " -t, ";
        const string SpecialDelimiterArg = " -t$$ -r## ";


		int m_sid;
		DirectoryInfo m_di;
		string m_stamp,
			m_cabfile = "";
		int m_Status = 0;
		bool bForceDate = false,
			bForceSid = false;
		DateTime forceDate;
        static List<TableToExport> tablesToExport;


        static Exporter ()
        {
            tablesToExport = new List<TableToExport> ();

            tablesToExport.Add (new TableToExport ("sys_config", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("mgr_collector", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("x_session", TableExportMode.TopQuery, 20));

            // Catalogs
            tablesToExport.Add (new TableToExport ("mgr_host", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("mgr_server", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("mgr_instance", TableExportMode.WholeTable));

            // Dictionaries
            tablesToExport.Add (new TableToExport ("", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_DiskModel", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_NIC", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_qfe", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_qfe_component", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dp_counters", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_processor", TableExportMode.WholeTable, true));
            tablesToExport.Add (new TableToExport ("dc_product", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_vendor", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_service", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_task", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_column", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("dc_optimizer", TableExportMode.WholeTable));

            // Snapshots ('true' state tables)
            tablesToExport.Add (new TableToExport ("c_database", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_dbfile", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_filegroup", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_DiskDrive", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_errorlog", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_event_counts", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_instance", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_last_log", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_NIC", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_NICconfig", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_processor", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_qfe", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_syscurconfigs", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_trace", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_watson", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_wmi_logfile", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_wmi_OS", TableExportMode.WholeTable, true));
            tablesToExport.Add (new TableToExport ("c_wmi_CS", TableExportMode.WholeTable, true));
            tablesToExport.Add (new TableToExport ("c_product", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_service", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_task", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_assembly_types", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_columns", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_database2", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_dataspace", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_dbobjects", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_endpoints", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_event_notifications", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_imail", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_instance2", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_internal_tables", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_linked_servers", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_notification_subscriptions", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_partition_function", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_partition_parameters", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_partition_scheme", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_triggers", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_sb", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_ft", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_assemblies", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_indexes", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_backups", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_badpagehistory", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_rs", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_cursors", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_optimizer", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_certificates", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_globalTraceFlags", TableExportMode.WholeTable));
            tablesToExport.Add (new TableToExport ("c_TableTextInRowLimit", TableExportMode.WholeTable));


            // Special snapshots
            tablesToExport.Add (new TableToExport ("c_sql_log_cap", TableExportMode.WholeTable));


            // Run-bound data
            // run log
            tablesToExport.Add (new TableToExport ("mgr_run", TableExportMode.RunQuery, false));
            tablesToExport.Add (new TableToExport ("mgr_run_detail", TableExportMode.RunQuery, false));
            tablesToExport.Add (new TableToExport ("mgr_unit", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("mgr_run_error", TableExportMode.RunQuery, true));

            // historical data (time-based)
            tablesToExport.Add (new TableToExport ("c_av", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("c_dumps", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("c_os_outage", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("c_sql_outage", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("c_trace_history", TableExportMode.RunQuery, false));
            tablesToExport.Add (new TableToExport ("c_watson_event", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("c_sysperf", TableExportMode.RunQuery, false));

            // special
            tablesToExport.Add (new TableToExport ("c_log_history", TableExportMode.RunQuery, false));
            tablesToExport.Add (new TableToExport ("mgr_dbobject_reftime", TableExportMode.RunQuery, false));

            // static & dynamic state tracking
            tablesToExport.Add (new TableToExport ("hs_database", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_database", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_dbfile", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_dbfile", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_DiskDrive", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_errorlog", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_errorlog", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_event_counts", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_filegroup", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_filegroup", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_instance", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_NIC", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_NICconfig", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_processor", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_qfe", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_syscurconfigs", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_trace", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_watson", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_wmi_CS", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("hs_wmi_logfile", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_wmi_logfile", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_wmi_OS", TableExportMode.RunQuery, true));
            tablesToExport.Add (new TableToExport ("hd_wmi_OS", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_product", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_service", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_task", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_assembly_types", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_columns", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_database2", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_dataspace", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_dbobjects", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_endpoints", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_event_notifications", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_imail", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_instance2", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_internal_tables", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_linked_servers", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_notification_subscriptions", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_partition_function", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_partition_parameters", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_partition_scheme", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_triggers", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_sb", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_ft", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_assemblies", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_indexes", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_backups", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_badpagehistory", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_rs", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_cursors", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_optimizer", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_certificates", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hd_globalTraceFlags", TableExportMode.RunQuery));
            tablesToExport.Add (new TableToExport ("hs_TableTextInRowLimit", TableExportMode.RunQuery));

            // Perf (file-bound)
            tablesToExport.Add (new TableToExport ("p_files", TableExportMode.FileQuery));
            tablesToExport.Add (new TableToExport ("perf", TableExportMode.FileQuery));

        }

		public Exporter ()
		{
			if (CmdLineArg.bExporterForceSid)
			{
				bForceSid = true;
				m_sid = (int)CmdLineArg.ForceSid;
				return;
			}
			if (CmdLineArg.bExporterForceDate)
			{
				bForceDate = true;
				forceDate = CmdLineArg.ForceDate;
			}
		}

		public void Init ()
		{
			int nAttempts=10,
				i=0;
			string p, path;
            Exception ex = null;

			m_stamp = DateTime.Now.ToString ("MMddyyHHmmss");
			p = "Data\\"+m_stamp;
			path = p;
			while (i<nAttempts)
			{
				++i;
				try
				{
					m_di = Directory.CreateDirectory (path);
					m_cabfile = "Data\\"+H2Manager.dbGuid+" "+m_stamp+".cab";
					if (bForceSid) 
					{
						ChangeStatus ("Export session "+m_sid+" forced through command-line switch.", StatusEventType.WARNING);
					}
 					return;
				}
				catch (IOException ioex)
				{
                    ex = ioex;
					if (ioex.Message.StartsWith ("There is not enough space on the disk."))
					{
                        H2Manager.LogMgrError (0, 0, RunErrorClass.Exporter, 0, "Exporter", CollectorError.ExportedNoDiskSpace, 0, ioex.Message);
						ChangeStatus (ioex.Message, StatusEventType.ERROR);
						throw;
					}
					path = p+"."+i;
				}
			}

			if (m_di == null) 
			{
                H2Manager.LogMgrError (0, 0, RunErrorClass.Exporter, 0, "Exporter", CollectorError.ExporterCannotInit, 0, "Unable to create a temporary directory.");
                throw ex;
			}
		}

		public static bool CheckPermissions ()
		{
			SqlCommand cmd = new SqlCommand ("Select ivalue From sys_config Where config=1000",
				H2Manager.Repository.SQLConnection);

			object obj = cmd.ExecuteScalar ();
			if (obj != null)
			{
				int w = (int)obj;

				if (w == 1)
				{
					return true;
				}
			}

			return false;
		}

		void RegisterSession ()
		{
			SqlCommand rcmd;
			SqlParameter p_sid,
				p_host,
				retval;
			int retcode;

			rcmd = new SqlCommand ("dbo.spr_xsession", H2Manager.Repository.SQLConnection);
			rcmd.CommandType = CommandType.StoredProcedure;

			retval = new SqlParameter ("retvalue", SqlDbType.Int);
			retval.Direction = ParameterDirection.ReturnValue;
			rcmd.Parameters.Add (retval);
			p_sid = new SqlParameter ("@sid", SqlDbType.Int);
			p_sid.Direction = ParameterDirection.Output;
			rcmd.Parameters.Add (p_sid);
			p_host = new SqlParameter ("@host_id", SqlDbType.Int);
			p_host.Value = H2Manager.HostID;
			rcmd.Parameters.Add (p_host);
			if (bForceDate)
			{
				SqlParameter p_date = new SqlParameter ("@forceDate", SqlDbType.DateTime);
				p_date.Value = forceDate;
				rcmd.Parameters.Add (p_date);
			}

			rcmd.ExecuteNonQuery ();
			try 
			{
				retcode = (int)retval.Value;
				m_sid = (int)p_sid.Value;
				ChangeStatus ("XSession sid = "+m_sid, StatusEventType.INFO);
			}
			catch (SqlException sqlex)
			{
				H2Manager.Log.SQLException (sqlex);
				ChangeStatus (sqlex.StackTrace, StatusEventType.STACK_TRACE);
				throw (new StorageErrorException (CollectorError.StorSyntaxErrorReaderSP,sqlex.Number,"dbo.spr_xsession"));
			}
		}

		void RollbackSessionRuns ()
		{
			if (!bForceSid)
			{
				string cmd = "Delete x_runs Where sid="+m_sid;
				H2Manager.Repository.StoreNonQuery (cmd);

				cmd = "Delete x_files Where sid="+m_sid;
				H2Manager.Repository.StoreNonQuery (cmd);

				ChangeStatus ("Export session "+m_sid+" rolled back");
			}
		}

		void CreateIDFile (ExportSessionType a_type)
		{
			string fname = m_di.FullName+"\\ID.txt";

			StreamWriter sw = new StreamWriter (fname);

			int type = (int)a_type;
			sw.WriteLine (H2Manager.HostID+","+H2Manager.dbGuid+","+m_sid+","+type+","+Constants.RepositoryVersion);
			sw.Close ();
		}

		public void Run ()
		{
			ExportSessionType estype;

			if (bForceSid)
			{
				estype = ExportSessionType.FORCED;
			}
			else
			{
				estype = ExportSessionType.NEW;
			}

			try
			{
				RunSession (estype);

                CabResults ();
			}
			catch (Exception ex)
			{
				UpdateStatus ();
                H2Manager.LogMgrError (0, 0, RunErrorClass.Exporter, 0, "Exporter", CollectorError.ExporterProcessFailure, 0, ex.Message);
				ChangeStatus (ex.Message, StatusEventType.ERROR);
				RollbackSessionRuns ();
				throw ex;
			}
		}

		void RunSession (ExportSessionType a_type)
		{
            string outfile = String.Empty;
            string query = String.Empty;
            string innerQuery = String.Empty;
            string arguments = String.Empty;

			if (a_type == ExportSessionType.NEW) RegisterSession (); 

			CreateIDFile (a_type);

			Process p=new Process ();
			p.StartInfo.FileName = "bcp.exe";
			p.StartInfo.CreateNoWindow = true;
			p.StartInfo.UseShellExecute = false;
			p.StartInfo.RedirectStandardOutput = true;

			try
			{
                foreach (TableToExport tte in tablesToExport)
                {
                    ChangeStatus (" Exporting " + tte.Name);

                    outfile = m_di.FullName + (tte.SpecialDelimeter ? "\\_" : "\\") + tte.Name + ".txt";

                    switch (tte.Mode)
                    {
                        case TableExportMode.WholeTable:
                            query = String.Format (EntireTableArgs,
                                Constants.QuotedRepositoryDB, tte.Name, outfile, Constants.RepositoryServer);
                            break;
                        case TableExportMode.RunQuery:
                            innerQuery = String.Format (RunQueryArgs,
                                Constants.QuotedRepositoryDB, tte.Name, m_sid);
                            query = String.Format (QueryOutArgs, query, outfile, Constants.RepositoryServer);
                            break;
                        case TableExportMode.TopQuery:
                            innerQuery = String.Format (TopQueryArgs,
                                tte.TopNumber.ToString (), Constants.QuotedRepositoryDB, tte.Name);
                            query = String.Format (QueryOutArgs, query, outfile, Constants.RepositoryServer);
                            break;
                        case TableExportMode.FileQuery:
                            innerQuery = String.Format (FileQueryArgs,
                                Constants.QuotedRepositoryDB, tte.Name, m_sid);
                            query = String.Format (QueryOutArgs, query, outfile, Constants.RepositoryServer);
                            break;
                    }

                    arguments = query + (tte.SpecialDelimeter ? SpecialDelimiterArg : RegularDelimiterArg);

                    RunProcess (p, arguments);
                }

				m_Status = 1000;
				ChangeStatus ("Exporting Data finished");
			}
			catch (System.ComponentModel.Win32Exception wex)
			{
				if (wex.NativeErrorCode == 2)
				{
					string msg = "Could not find bcp.exe. (You can install BCP by installing SQL Server Client Tools on the system.)";
                    H2Manager.LogMgrError (0, 0, RunErrorClass.Exporter, 1, "Exporter", CollectorError.ExternalCannotFindBcp, wex.NativeErrorCode, msg);
					throw new Exception (msg);
				}
				else
				{
					throw;
				}
			}
			finally
			{
				p.Close ();
			}
	
		}

		void UpdateStatus ()
		{
			if (bForceSid) return;

			string ucmd = "Update "+Constants.RepositoryDB+".dbo.x_session Set "
				+"state = "+m_Status+", dt_finish = GETDATE() "
				+"Where sid="+m_sid;
			H2Manager.Repository.StoreNonQuery (ucmd);
		}

		int RunProcess (Process a_p, string a_args)
		{
			int ExitCode=0;
			string output = "",
				s_ioerror = "I/O error while writing BCP data-file";

				
			a_p.StartInfo.Arguments = a_args;
			ChangeStatus (a_p.StartInfo.Arguments, StatusEventType.DEBUG);

			m_Status++;
			a_p.Start ();
			output = a_p.StandardOutput.ReadToEnd();
			a_p.WaitForExit();
			ExitCode = a_p.ExitCode;

			ChangeStatus (output, StatusEventType.DEBUG);
			if (output.IndexOf (s_ioerror) > 0)
			{
				throw new Exception (s_ioerror);
			}

			return ExitCode;
		}

		bool CabResults ()
		{
			string Arguments;

			Process p=new Process ();
			p.StartInfo.FileName = "cabarc.exe";
			p.StartInfo.CreateNoWindow = true;
			p.StartInfo.UseShellExecute = false;
			p.StartInfo.RedirectStandardOutput = true;

			Arguments = "N \""+m_cabfile+"\" \""+m_di.FullName+"\\*.*\"";
			ChangeStatus (" Creating cab-file");
			int r = RunProcess (p, Arguments);
			ChangeStatus (" Operation completed (ExitCode="+r+")");
			p.Close ();
			
			return (r == 0);
		}

		void Clean ()
		{
			try
			{
				if (!CmdLineArg.bExporterRetainFiles)
				{
					ChangeStatus (" deleting temporary files");
					m_di.Delete (true);
				}
			}
			catch (Exception ex)
			{
                H2Manager.LogMgrError (0, 0, RunErrorClass.Exporter, 0, "Exporter", CollectorError.ExporterCannotClean, 0, ex.Message);
				ChangeStatus (ex.Message, StatusEventType.ERROR);
				ChangeStatus ("Export session finished successfully, but failed to delete temporary files. The files have to be deleted manually.", 
					StatusEventType.WARNING);
			}
		}
	}
}
